package com.elastic;


import com.elastic.bean.Hotel;
import com.elastic.es.HotelRepository;
import com.elastic.service.IHotelService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.BulkByScrollTask;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.*;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ElasticApplication.class)
public class TeatEsHotel {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private HotelRepository hotelRepository;


    @Autowired
    private IHotelService iHotelService;


    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;




    @Test
    public void testGetHotel() throws IOException {

        SearchRequest request = new SearchRequest("hotel");

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();


        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.rangeQuery("score").gte(60).lte(90));

        sourceBuilder.query(boolQueryBuilder);

        request.source(sourceBuilder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);

        System.out.println(search);
    }

    @Test
    public void updateHotel() throws IOException {
        UpdateByQueryRequest request = new UpdateByQueryRequest("hotel");
        request.setRefresh(true);

        request.setQuery(QueryBuilders.termQuery("city","杭州"));
        HashMap<String, Object> params = new HashMap<>();
        params.put("pic","gggggggggg");
        params.put("starName","五星级");

        request.setScript(new Script(ScriptType.INLINE,"painless","ctx._source.pic=params.pic;ctx._source.starName=params.starName",params));

        BulkByScrollResponse bulkByScrollResponse = client.updateByQuery(request, RequestOptions.DEFAULT);

        BulkByScrollTask.Status status = bulkByScrollResponse.getStatus();

        System.out.println(status);


    }

    @Test
    public void saveHotel(){

        List<Long> list = new ArrayList<>();
        list.add(60367L);
        list.add(60368L);
        list.add(60359L);

        Hotel byId = iHotelService.getById(60359L);

        hotelRepository.save(byId);


//        List<Hotel> allByIdIn = hotelRepository.findAllByIdIn(list);
//
//        System.out.println(allByIdIn);

//        List<Hotel> hotels = hotelRepository.findAllByCity("上海");

//        Hotel hotel = hotelRepository.findById(60367L).orElse(null);

//        List<Hotel> hotelList = hotels.stream().peek(h -> h.setPic("gs")).collect(Collectors.toList());
//
//        hotelRepository.saveAll(hotelList);

//         hotelRepository.deleteByCityAndPrice("上海",3299);

//        List<Hotel> byIds = iHotelService.getByIds(list);
//
//        Iterable<Hotel> hotels = hotelRepository.saveAll(byIds);
//
//        System.out.println(hotels);

//        boolean b = iHotelService.deleteByIds(list);

//        List<UpdateHotelParam> list1 = new ArrayList<>();
//
//        UpdateHotelParam param1 = new UpdateHotelParam();
//        param1.setId(60367L);
//        param1.setPic("aab");
//        param1.setPrice(null);
//
//        UpdateHotelParam param2 = new UpdateHotelParam();
//        param2.setId(60368L);
//        param2.setPic("ccd");
//        param2.setPrice(600);
//
//        list1.add(param1);
//        list1.add(param2);
//
//        boolean b = iHotelService.updateByIds(list1);
//
//        System.out.println(b);


    }

    @Test
    public void testBulkDelete(){

//        List<Long> ids = new ArrayList<>();
//
//        BulkRequest bulkRequest = new BulkRequest();
//
//        for (Long id : ids) {
//            DeleteRequest deleteRequest = new DeleteRequest("hotel",id.toString());
//            bulkRequest.add(deleteRequest);
//        }


//        String delete = elasticsearchTemplate.delete("60359", Hotel.class);

        Hotel hotel = elasticsearchTemplate.get("60367", Hotel.class);



        System.out.println(hotel);

    }

    @Test
    public void testUpdateRes(){

        List<UpdateQuery> updateQueries = new ArrayList<>();

        List<Long> list = new ArrayList<>();
        list.add(60367L);
        list.add(60368L);
        list.add(60359L);

        for (Long id : list) {
//            UpdateQuery build = UpdateQuery.builder(id.toString()).withDocument().build();
        }
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        NativeSearchQuery query = nativeSearchQueryBuilder.build();


        elasticsearchTemplate.search(query,Hotel.class);

    }

    @Test
    public void testGetIds() throws IOException {


        List<Long> list = new ArrayList<>();
        list.add(60367L);
        list.add(60368L);
        list.add(60359L);
        SearchRequest request = new SearchRequest("hotel");

        SearchSourceBuilder builder = new SearchSourceBuilder();

         builder.query(QueryBuilders.idsQuery().addIds(new String[]{"60367","60368"}));

        request.source(builder);


        SearchResponse search = client.search(request, RequestOptions.DEFAULT);

        System.out.println(search);

    }

    @Test
    public void testTerms() throws IOException {


        List<Long> list = new ArrayList<>();
        list.add(60367L);
        list.add(60368L);
        list.add(60359L);

        List<String> years = new ArrayList<>();
        years.add("2007");
        years.add("1995");

        SearchRequest request = new SearchRequest("movies");

        TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("year",years);

        SearchSourceBuilder builder = new SearchSourceBuilder();

        builder.query(termsQueryBuilder);

        request.source(builder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);

        System.out.println(search);


    }

    @Test
    public void testTermsMovies() throws IOException {


        SearchSourceBuilder builder = new SearchSourceBuilder();

        List<String> years = new ArrayList<>();
        years.add("2007");
        years.add("1995");

        SearchSourceBuilder sourceBuilder = builder.query(QueryBuilders.termsQuery("year", years));

        sourceBuilder.from(1);
        sourceBuilder.size(10);


        SearchRequest request = new SearchRequest("movies");


        request.source(sourceBuilder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);


        System.out.println(search);


    }

    @Test
    public void testMatch() throws IOException {

        SearchRequest request = new SearchRequest("movies");

        SearchSourceBuilder builder = new SearchSourceBuilder();

        List<String> years = new ArrayList<>();
        years.add("2007");
        years.add("1995");

        SearchSourceBuilder year = builder.query(QueryBuilders.matchQuery("title", "Father of the"));

        request.source(year);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);

        System.out.println(search);


    }

    @Test
    public  void testFuzzyQuery() throws IOException {
        SearchRequest request = new SearchRequest("hotel");


        SearchSourceBuilder builder = new SearchSourceBuilder();
        //这里的Fuzziness.TWO是查询结果的字符串长度偏差，可以设置成Fuzziness.ONE看一下效果
//        builder.query(QueryBuilders.fuzzyQuery("name", "上海康"));
//        builder.query(QueryBuilders.wildcardQuery("name",String.format("%s%s%s","*","上海康桥万豪","*")));


        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.wildcardQuery("name", "*" + "迪士尼" + "*"));
        boolQueryBuilder.should(QueryBuilders.wildcardQuery("starName", "*" + "星级" + "*"));
        builder.query(boolQueryBuilder);



        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        SearchHits hits = response.getHits();

        System.out.println(hits.getTotalHits());
        System.out.println(response.getTook());

        for ( SearchHit hit : hits ) {
            System.out.println(hit.getSourceAsString());
        }

    }




















}
